home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / in_dos.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  12KB  |  616 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // in_mouse.c -- dos mouse code
  21.  
  22. #include "quakedef.h"
  23. #include "dosisms.h"
  24.  
  25. #define AUX_FLAG_FREELOOK    0x00000001
  26.  
  27. typedef struct
  28. {
  29.     long    interruptVector;
  30.     char    deviceName[16];
  31.     long    numAxes;
  32.     long    numButtons;
  33.     long    flags;
  34.     
  35.     vec3_t  viewangles;
  36.  
  37. // intended velocities
  38.     float   forwardmove;
  39.     float   sidemove;
  40.     float   upmove;
  41.  
  42.     long    buttons;
  43. } externControl_t;
  44.  
  45. /*
  46. #define AUX_FLAG_FORCEFREELOOK    0x00000001    // r/o
  47. #define AUX_FLAG_EXTENDED        0x00000002    // r/o
  48. #define AUX_FLAG_RUN            0x00000004    // w/o
  49. #define AUX_FLAG_STRAFE            0x00000008    // w/o
  50. #define AUX_FLAG_FREELOOK        0x00000010    // w/o
  51.  
  52. #define AUX_MAP_UNDEFINED    0
  53. #define AUX_MAP_PITCH        1
  54. #define AUX_MAP_YAW            2
  55. #define AUX_MAP_ROLL        3
  56. #define AUX_MAP_FORWARD        4
  57. #define AUX_MAP_SIDE        5
  58. #define AUX_MAP_UP            6
  59.  
  60. typedef struct
  61. {
  62.     long    interruptVector;
  63.     // r/o
  64.     char    deviceName[16];
  65.     // r/o
  66.     long    numAxes;
  67.             // r/o    1-6
  68.     long    numButtons;            // r/o    0-32
  69.     long    flags;                // see above
  70.     byte    axisMapping[6];        // w/o    default = p,y,r,f,s,u
  71.     float    axisValue[6];        // r/w
  72.     float    sensitivity[6];        // w/o    default = 1.0
  73.     long    buttons;            // r/o
  74.     float    last_frame_time;    // w/o
  75. } externControl_t;
  76. */
  77.  
  78. cvar_t    m_filter = {"m_filter","1"};
  79.  
  80. qboolean    mouse_avail;
  81. int        mouse_buttons;
  82. int        mouse_oldbuttonstate;
  83. int        mouse_buttonstate;
  84. float    mouse_x, mouse_y;
  85. float    old_mouse_x, old_mouse_y;
  86.  
  87.  
  88. cvar_t    in_joystick = {"joystick","1"};
  89. cvar_t    joy_numbuttons = {"joybuttons","4", true};
  90.  
  91. qboolean    joy_avail;
  92. int        joy_oldbuttonstate;
  93. int        joy_buttonstate;
  94.  
  95. int     joyxl, joyxh, joyyl, joyyh; 
  96. int        joystickx, joysticky;
  97.  
  98. qboolean        need_center;
  99.  
  100. qboolean        extern_avail;
  101. int                extern_buttons;
  102. int                extern_oldbuttonstate;
  103. int                extern_buttonstate;
  104. cvar_t    aux_look = {"auxlook","1", true};
  105. externControl_t    *extern_control;
  106. void IN_StartupExternal (void);
  107. void IN_ExternalMove (usercmd_t *cmd);
  108.  
  109. void IN_StartupJoystick (void);
  110. qboolean IN_ReadJoystick (void);
  111.  
  112.  
  113. void Toggle_AuxLook_f (void)
  114. {
  115.     if (aux_look.value)
  116.         Cvar_Set ("auxlook","0");
  117.     else
  118.         Cvar_Set ("auxlook","1");
  119. }
  120.  
  121.  
  122. void Force_CenterView_f (void)
  123. {
  124.     cl.viewangles[PITCH] = 0;
  125. }
  126.  
  127.  
  128. /*
  129. ===========
  130. IN_StartupMouse
  131. ===========
  132. */
  133. void IN_StartupMouse (void)
  134. {
  135.     if ( COM_CheckParm ("-nomouse") ) 
  136.         return; 
  137.  
  138. // check for mouse
  139.     regs.x.ax = 0;
  140.     dos_int86(0x33);
  141.     mouse_avail = regs.x.ax;
  142.     if (!mouse_avail)
  143.     {
  144.         Con_Printf ("No mouse found\n");
  145.         return;
  146.     }
  147.     
  148.     mouse_buttons = regs.x.bx;
  149.     if (mouse_buttons > 3)
  150.         mouse_buttons = 3;
  151.     Con_Printf("%d-button mouse available\n", mouse_buttons);
  152. }
  153.  
  154. /*
  155. ===========
  156. IN_Init
  157. ===========
  158. */
  159. void IN_Init (void)
  160. {
  161.     int i;
  162.  
  163.     Cvar_RegisterVariable (&m_filter);
  164.     Cvar_RegisterVariable (&in_joystick);
  165.     Cvar_RegisterVariable (&joy_numbuttons);
  166.     Cvar_RegisterVariable (&aux_look);
  167.     Cmd_AddCommand ("toggle_auxlook", Toggle_AuxLook_f);
  168.     Cmd_AddCommand ("force_centerview", Force_CenterView_f);
  169.  
  170.     IN_StartupMouse ();
  171.     IN_StartupJoystick ();
  172.  
  173.     i = COM_CheckParm ("-control");
  174.     if (i)
  175.     {
  176.         extern_control = real2ptr(Q_atoi (com_argv[i+1]));
  177.         IN_StartupExternal ();
  178.     }
  179. }
  180.  
  181. /*
  182. ===========
  183. IN_Shutdown
  184. ===========
  185. */
  186. void IN_Shutdown (void)
  187. {
  188.  
  189. }
  190.  
  191.  
  192. /*
  193. ===========
  194. IN_Commands
  195. ===========
  196. */
  197. void IN_Commands (void)
  198. {
  199.     int        i;
  200.  
  201.     if (mouse_avail)
  202.     {
  203.         regs.x.ax = 3;        // read buttons
  204.         dos_int86(0x33);
  205.         mouse_buttonstate = regs.x.bx;
  206.     
  207.     // perform button actions
  208.         for (i=0 ; i<mouse_buttons ; i++)
  209.         {
  210.             if ( (mouse_buttonstate & (1<<i)) &&
  211.             !(mouse_oldbuttonstate & (1<<i)) )
  212.             {
  213.                 Key_Event (K_MOUSE1 + i, true);
  214.             }
  215.             if ( !(mouse_buttonstate & (1<<i)) &&
  216.             (mouse_oldbuttonstate & (1<<i)) )
  217.             {
  218.                 Key_Event (K_MOUSE1 + i, false);
  219.             }
  220.         }    
  221.         
  222.         mouse_oldbuttonstate = mouse_buttonstate;
  223.     }
  224.     
  225.     if (joy_avail)
  226.     {
  227.         joy_buttonstate = ((dos_inportb(0x201) >> 4)&15)^15;
  228.     // perform button actions
  229.         for (i=0 ; i<joy_numbuttons.value ; i++)
  230.         {
  231.             if ( (joy_buttonstate & (1<<i)) &&
  232.             !(joy_oldbuttonstate & (1<<i)) )
  233.             {
  234.                 Key_Event (K_JOY1 + i, true);
  235.             }
  236.             if ( !(joy_buttonstate & (1<<i)) &&
  237.             (joy_oldbuttonstate & (1<<i)) )
  238.             {
  239.                 Key_Event (K_JOY1 + i, false);
  240.             }
  241.         }
  242.         
  243.         joy_oldbuttonstate = joy_buttonstate;
  244.     }
  245.  
  246.     if (extern_avail)
  247.     {
  248.         extern_buttonstate = extern_control->buttons;
  249.     
  250.     // perform button actions
  251.         for (i=0 ; i<extern_buttons ; i++)
  252.         {
  253.             if ( (extern_buttonstate & (1<<i)) &&
  254.             !(extern_oldbuttonstate & (1<<i)) )
  255.             {
  256.                 Key_Event (K_AUX1 + i, true);
  257.             }
  258.             if ( !(extern_buttonstate & (1<<i)) &&
  259.             (extern_oldbuttonstate & (1<<i)) )
  260.             {
  261.                 Key_Event (K_AUX1 + i, false);
  262.             }
  263.         }    
  264.         
  265.         extern_oldbuttonstate = extern_buttonstate;
  266.     }
  267.     
  268. }
  269.  
  270.  
  271. /*
  272. ===========
  273. IN_Move
  274. ===========
  275. */
  276. void IN_MouseMove (usercmd_t *cmd)
  277. {
  278.     int        mx, my;
  279.  
  280.     if (!mouse_avail)
  281.         return;
  282.  
  283.     regs.x.ax = 11;        // read move
  284.     dos_int86(0x33);
  285.     mx = (short)regs.x.cx;
  286.     my = (short)regs.x.dx;
  287.     
  288.     if (m_filter.value)
  289.     {
  290.         mouse_x = (mx + old_mouse_x) * 0.5;
  291.         mouse_y = (my + old_mouse_y) * 0.5;
  292.     }
  293.     else
  294.     {
  295.         mouse_x = mx;
  296.         mouse_y = my;
  297.     }
  298.     old_mouse_x = mx;
  299.     old_mouse_y = my;
  300.  
  301.     mouse_x *= sensitivity.value;
  302.     mouse_y *= sensitivity.value;
  303.  
  304. // add mouse X/Y movement to cmd
  305.     if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
  306.         cmd->sidemove += m_side.value * mouse_x;
  307.     else
  308.         cl.viewangles[YAW] -= m_yaw.value * mouse_x;
  309.     
  310.     if (in_mlook.state & 1)
  311.         V_StopPitchDrift ();
  312.         
  313.     if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
  314.     {
  315.         cl.viewangles[PITCH] += m_pitch.value * mouse_y;
  316.         if (cl.viewangles[PITCH] > 80)
  317.             cl.viewangles[PITCH] = 80;
  318.         if (cl.viewangles[PITCH] < -70)
  319.             cl.viewangles[PITCH] = -70;
  320.     }
  321.     else
  322.     {
  323.         if ((in_strafe.state & 1) && noclip_anglehack)
  324.             cmd->upmove -= m_forward.value * mouse_y;
  325.         else
  326.             cmd->forwardmove -= m_forward.value * mouse_y;
  327.     }
  328. }
  329.  
  330. /*
  331. ===========
  332. IN_JoyMove
  333. ===========
  334. */
  335. void IN_JoyMove (usercmd_t *cmd)
  336. {
  337.     float    speed, aspeed;
  338.  
  339.     if (!joy_avail || !in_joystick.value) 
  340.         return; 
  341.  
  342.     IN_ReadJoystick (); 
  343.     if (joysticky > joyyh*2 || joystickx > joyxh*2)
  344.         return;        // assume something jumped in and messed up the joystick
  345.                     // reading time (win 95)
  346.  
  347.     if (in_speed.state & 1)
  348.         speed = cl_movespeedkey.value;
  349.     else
  350.         speed = 1;
  351.     aspeed = speed*host_frametime;
  352.  
  353.     if (in_strafe.state & 1)
  354.     {
  355.         if (joystickx < joyxl)
  356.             cmd->sidemove -= speed*cl_sidespeed.value; 
  357.         else if (joystickx > joyxh) 
  358.             cmd->sidemove += speed*cl_sidespeed.value; 
  359.     }
  360.     else
  361.     {
  362.         if (joystickx < joyxl)
  363.             cl.viewangles[YAW] += aspeed*cl_yawspeed.value;
  364.         else if (joystickx > joyxh) 
  365.             cl.viewangles[YAW] -= aspeed*cl_yawspeed.value;
  366.         cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]);
  367.     }
  368.  
  369.     if (in_mlook.state & 1)
  370.     {
  371.         if (m_pitch.value < 0)
  372.             speed *= -1;
  373.         
  374.         if (joysticky < joyyl) 
  375.             cl.viewangles[PITCH] += aspeed*cl_pitchspeed.value;
  376.         else if (joysticky > joyyh) 
  377.             cl.viewangles[PITCH] -= aspeed*cl_pitchspeed.value;
  378.     }
  379.     else
  380.     {
  381.         if (joysticky < joyyl) 
  382.             cmd->forwardmove += speed*cl_forwardspeed.value; 
  383.         else if (joysticky > joyyh) 
  384.             cmd->forwardmove -= speed*cl_backspeed.value;  
  385.     }
  386. }
  387.  
  388. /*
  389. ===========
  390. IN_Move
  391. ===========
  392. */
  393. void IN_Move (usercmd_t *cmd)
  394. {
  395.     IN_MouseMove (cmd);
  396.     IN_JoyMove (cmd);
  397.     IN_ExternalMove (cmd);
  398. }
  399.  
  400. /* 
  401. ============================================================================ 
  402.  
  403.                     JOYSTICK 
  404.  
  405. ============================================================================ 
  406. */
  407.  
  408.  
  409.  
  410. qboolean IN_ReadJoystick (void)
  411. {
  412.     int        b;
  413.     int        count;
  414.  
  415.     joystickx = 0;
  416.     joysticky = 0;
  417.  
  418.     count = 0;
  419.  
  420.     b = dos_inportb(0x201);
  421.     dos_outportb(0x201, b);
  422.  
  423. // clear counters
  424.     while (++count < 10000)
  425.     {
  426.         b = dos_inportb(0x201);
  427.  
  428.         joystickx += b&1;
  429.         joysticky += (b&2)>>1;
  430.         if ( !(b&3) )
  431.             return true;
  432.     }
  433.     
  434.     Con_Printf ("IN_ReadJoystick: no response\n");
  435.     joy_avail = false;
  436.     return false;
  437. }
  438.  
  439. /*
  440. =============
  441. WaitJoyButton
  442. =============
  443. */
  444. qboolean WaitJoyButton (void) 
  445.     int             oldbuttons, buttons; 
  446.  
  447.     oldbuttons = 0; 
  448.     do 
  449.     {
  450.         key_count = -1;
  451.         Sys_SendKeyEvents ();
  452.         key_count = 0;
  453.         if (key_lastpress == K_ESCAPE)
  454.         {
  455.             Con_Printf ("aborted.\n");
  456.             return false;
  457.         }
  458.         key_lastpress = 0;
  459.         SCR_UpdateScreen ();
  460.         buttons =  ((dos_inportb(0x201) >> 4)&1)^1; 
  461.         if (buttons != oldbuttons) 
  462.         { 
  463.             oldbuttons = buttons; 
  464.             continue; 
  465.         }
  466.     } while ( !buttons); 
  467.  
  468.     do 
  469.     { 
  470.         key_count = -1;
  471.         Sys_SendKeyEvents ();
  472.         key_count = 0;
  473.         if (key_lastpress == K_ESCAPE)
  474.         {
  475.             Con_Printf ("aborted.\n");
  476.             return false;
  477.         }
  478.         key_lastpress = 0;
  479.         SCR_UpdateScreen ();
  480.         buttons =  ((dos_inportb(0x201) >> 4)&1)^1; 
  481.         if (buttons != oldbuttons) 
  482.         { 
  483.             oldbuttons = buttons; 
  484.             continue; 
  485.         } 
  486.     } while ( buttons); 
  487.  
  488.     return true; 
  489.  
  490.  
  491.  
  492. /* 
  493. =============== 
  494. IN_StartupJoystick 
  495. =============== 
  496. */  
  497. void IN_StartupJoystick (void) 
  498.     int     centerx, centery; 
  499.  
  500.      Con_Printf ("\n");
  501.  
  502.     joy_avail = false; 
  503.     if ( COM_CheckParm ("-nojoy") ) 
  504.         return; 
  505.  
  506.     if (!IN_ReadJoystick ()) 
  507.     { 
  508.         joy_avail = false; 
  509.         Con_Printf ("joystick not found\n"); 
  510.         return; 
  511.     } 
  512.  
  513.     Con_Printf ("joystick found\n"); 
  514.  
  515.     Con_Printf ("CENTER the joystick\nand press button 1 (ESC to skip):\n"); 
  516.     if (!WaitJoyButton ()) 
  517.         return; 
  518.     IN_ReadJoystick (); 
  519.     centerx = joystickx; 
  520.     centery = joysticky; 
  521.  
  522.     Con_Printf ("Push the joystick to the UPPER LEFT\nand press button 1 (ESC to skip):\n"); 
  523.     if (!WaitJoyButton ()) 
  524.         return; 
  525.     IN_ReadJoystick (); 
  526.     joyxl = (centerx + joystickx)/2; 
  527.     joyyl = (centerx + joysticky)/2; 
  528.  
  529.     Con_Printf ("Push the joystick to the LOWER RIGHT\nand press button 1 (ESC to skip):\n"); 
  530.     if (!WaitJoyButton ()) 
  531.         return; 
  532.     IN_ReadJoystick (); 
  533.     joyxh = (centerx + joystickx)/2; 
  534.     joyyh = (centery + joysticky)/2; 
  535.  
  536.     joy_avail = true; 
  537.     Con_Printf ("joystick configured.\n"); 
  538.  
  539.      Con_Printf ("\n");
  540.  
  541.  
  542. /* 
  543. ============================================================================ 
  544.  
  545.                     EXTERNAL 
  546.  
  547. ============================================================================ 
  548. */
  549.  
  550.  
  551. /* 
  552. =============== 
  553. IN_StartupExternal 
  554. =============== 
  555. */  
  556. void IN_StartupExternal (void) 
  557.     if (extern_control->numButtons > 32)
  558.         extern_control->numButtons = 32;
  559.  
  560.     Con_Printf("%s Initialized\n", extern_control->deviceName);
  561.     Con_Printf("  %u axes  %u buttons\n", extern_control->numAxes, extern_control->numButtons);
  562.  
  563.     extern_avail = true;
  564.     extern_buttons = extern_control->numButtons;
  565. }
  566.  
  567.  
  568. /*
  569. ===========
  570. IN_ExternalMove
  571. ===========
  572. */
  573. void IN_ExternalMove (usercmd_t *cmd)
  574. {
  575.     qboolean freelook;
  576.  
  577.     if (! extern_avail)
  578.         return;
  579.  
  580.     extern_control->viewangles[YAW] = cl.viewangles[YAW];
  581.     extern_control->viewangles[PITCH] = cl.viewangles[PITCH];
  582.     extern_control->viewangles[ROLL] = cl.viewangles[ROLL];
  583.     extern_control->forwardmove = cmd->forwardmove;
  584.     extern_control->sidemove = cmd->sidemove;
  585.     extern_control->upmove = cmd->upmove;
  586.  
  587. Con_DPrintf("IN:  y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove);
  588.  
  589.     dos_int86(extern_control->interruptVector);
  590.  
  591. Con_DPrintf("OUT: y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove);
  592.  
  593.     cl.viewangles[YAW] = extern_control->viewangles[YAW];
  594.     cl.viewangles[PITCH] = extern_control->viewangles[PITCH];
  595.     cl.viewangles[ROLL] = extern_control->viewangles[ROLL];
  596.     cmd->forwardmove = extern_control->forwardmove;
  597.     cmd->sidemove = extern_control->sidemove;
  598.     cmd->upmove = extern_control->upmove;
  599.  
  600.     if (cl.viewangles[PITCH] > 80)
  601.         cl.viewangles[PITCH] = 80;
  602.     if (cl.viewangles[PITCH] < -70)
  603.         cl.viewangles[PITCH] = -70;
  604.  
  605.     freelook = (extern_control->flags & AUX_FLAG_FREELOOK || aux_look.value || in_mlook.state & 1);
  606.  
  607.     if (freelook)
  608.         V_StopPitchDrift ();
  609. }
  610.  
  611.